﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace WHControlLib
{
    public    class WHDataGridView   :DataGridView
    {



        public WHDataGridView()
        {
            //设置双缓冲开启禁止背景擦拭
            SetStyle(
                     ControlStyles.OptimizedDoubleBuffer
                     | ControlStyles.ResizeRedraw
                     | ControlStyles.Selectable
                     | ControlStyles.AllPaintingInWmPaint
                     | ControlStyles.UserPaint
                     | ControlStyles.SupportsTransparentBackColor,
                     true);

            //标题行风格
            ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.None;
            ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.True;
            RowHeadersDefaultCellStyle.SelectionForeColor = Color.White;
            ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;

            //禁用最后一行空白，自动新增行
            AllowUserToAddRows = false;
            AllowUserToDeleteRows = false;

            this.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
            //列占满行
            this.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;


            //禁止调整数据行行高
            AllowUserToResizeRows = false;

            //允许调整标题行行宽
            AllowUserToResizeColumns = true;


            //禁止行多选
            MultiSelect = false;

            //不显示数据行标题
            RowHeadersVisible = false;
            //  显示的数据内容剧中
            RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
     //AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;

            CellBorderStyle = DataGridViewCellBorderStyle.None;

        }

    

        private bool _isselectAllRowsMode;
        [Category("A我的表体"), Description("选择行的模式，true整行选择，false 可任选单元格"), Browsable(true)]
        public bool IsselectAllRowsMode
        {
            get { return _isselectAllRowsMode; }
            set {
                if (value)
                {
                    this.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                }
                else
                    this.SelectionMode = DataGridViewSelectionMode.CellSelect;

                _isselectAllRowsMode = value; }
        }



        private Color _titleColor=Color.Orange;
        [Category("A我的表头"), Description("表头的颜色，默认，橙色"), Browsable(true)]
        public Color TitleColor
        {
            get { return _titleColor; }
            set { _titleColor = value; }
        }

        private Color _titleFontColor=Color.Black;
        [Category("A我的表头"), Description("表头的字体颜色，默认，黑色"), Browsable(true)]
        public Color TitleFontColor
        {
            get { return _titleFontColor; }
            set { 
                  
                _titleFontColor = value; }


        }
        private Color _titleBorderColor = Color.Black;
        [Category("A我的表头"), Description("表头的边框颜色，默认，黑色"), Browsable(true)]
        public Color TitleBorderColor
        {
            get { return _titleBorderColor; }
            set { _titleBorderColor = value; }


        }

        private bool _isShowTitleHBorder=true;

        [Category("A我的表头"), Description("是否显示表头横边框，默认，true"), Browsable(true)]
        public bool  IsShowTitleHBorder
        {
            get { return _isShowTitleHBorder; }
            set { _isShowTitleHBorder = value; }
        }
        private bool _isShowTitleVBorder = true;
        [Category("A我的表头"), Description("是否显示表头竖边框，默认，true"), Browsable(true)]
        public bool IsShowTitleVBorder
        {
            get { return _isShowTitleVBorder; }
            set { _isShowTitleVBorder = value; }
        }
        private float _titleBorderWidth=2.0f;
    

    [Category("A我的表头"), Description("表头的边框宽度，默认，2.0f"), Browsable(true)]

    public float TitleBorderWidth
        {
            get { return _titleBorderWidth; }
            set { _titleBorderWidth = value; }
        }



        private Font _myTitleFont = new Font("微软雅黑", 12.0f, 0, GraphicsUnit.Point, 1);
        [Category("A我的表头"), Description(" 表头的字体，默认 微软雅黑12t"), Browsable(true)]
        public Font MyTitleFont
        {
            get { return _myTitleFont; }
            set {
                this.Font=value;
                _myTitleFont = value; this.Invalidate(); }
        }

        private Font _myCellFont = new Font("微软雅黑", 12.0f, 0, GraphicsUnit.Point, 1);
        [Category("A我的表体"), Description(" Cell的字体，默认 微软雅黑12t"), Browsable(true)]
        public Font MyCellFont
        {
            get { return _myCellFont; }
            set { this.RowsDefaultCellStyle.Font = value;
                _myCellFont = value; this.Invalidate(); }
        }
        private Color _myCellBackColor=Color.Orange;
        [Category("A我的表体"), Description(" Cell的背景色，默认  橙色"), Browsable(true)]
        public Color MyCellBackColor
        {
            get { return _myCellBackColor; }
            set {
                this.RowsDefaultCellStyle.BackColor = value;
                _myCellBackColor = value; }
        }

        private Color _myCellFontColor = Color.Black;
        [Category("A我的表体"), Description(" Cell字体颜色，默认  黑色"), Browsable(true)]
        public Color MyCellFontColor
        {
            get { return _myCellFontColor; }
            set
            {
                this.RowsDefaultCellStyle.ForeColor = value;
                _myCellFontColor = value;
            }
        }

        private bool _isShowCellHline=true;
        [Category("A我的表体"), Description("是否显示Cell的横边，默认，true"), Browsable(true)]
        public bool IsShowCellHLine
        {
            get { return _isShowCellHline; }
            set { _isShowCellHline = value; }
        }


        private bool _isShowCellVline = true;
        [Category("A我的表体"), Description("是否显示Cell的竖边，默认，true"), Browsable(true)]
        public bool IsShowCellVLine
        {
            get { return _isShowCellVline; }
            set { _isShowCellVline = value; }
        }


        private Color _myCellBorderColor=Color.Black;
        [Category("A我的表体"), Description("Cell的边颜色，默认，黑色"), Browsable(true)]
        public Color MyCellBorderColor
        {
            get { return _myCellBorderColor; }
            set { _myCellBorderColor = value; }
        }

        private float _myCellBorderWidth = 2.0f;


        [Category("A我的表体"), Description("Cell的边框宽度，默认，2.0f"), Browsable(true)]

        public float MyCellBorderWidth
        {
            get { return _myCellBorderWidth; }
            set { _myCellBorderWidth = value; }
        }

        private Color _selectedCellColor=Color.LightBlue;
        [Category("A我的表体"), Description("当Cell被选择时候的背景色，默认，亮蓝色"), Browsable(true)]
        public Color SelectedCellColor
        {
            get { return _selectedCellColor; }
            set { _selectedCellColor = value; }
        }
        private Color _selectedCellFontColor = Color.Black;
        [Category("A我的表体"), Description("当Cell被选择时候的字体颜色色，默认，黑色"), Browsable(true)]
        public Color SelectedCellFontColor
        {
            get { return _selectedCellFontColor; }
            set {
            

                RowsDefaultCellStyle.SelectionForeColor = value;
                _selectedCellFontColor = value; }
        }


        private bool _isUseAlternatingRowsColor;
        [Category("A我的表体"), Description("是否启用奇数行颜色，默认 false"), Browsable(true)]
        public bool IsUseAlternatingRowsColor
        {
            get { return _isUseAlternatingRowsColor; }
            set { _isUseAlternatingRowsColor = value; }
        }
        private Color _alternatingRowsColor=Color.Green;

     

        [Category("A我的表体"), Description("奇数行颜色，默认 绿色"), Browsable(true)]

        public Color AlternatingRowsColor
        {
            get { return _alternatingRowsColor; }
            set { _alternatingRowsColor = value; }
        }




        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            base.OnCellPainting(e);
            Graphics Myg = e.Graphics;
            Myg.CompositingQuality =CompositingQuality.HighQuality;
            Myg.SmoothingMode = SmoothingMode.HighQuality;


            StringFormat SfLeft = new StringFormat();
            SfLeft.LineAlignment = StringAlignment.Center;
            SfLeft.Alignment = StringAlignment.Near;

            StringFormat sfCenter = new StringFormat();
            sfCenter.LineAlignment = StringAlignment.Center;
            sfCenter.Alignment = StringAlignment.Center;
            //画出表头



            if (e.RowIndex == -1)
            {
                using (SolidBrush sb = new SolidBrush(TitleColor))
                {

                    Myg.FillRectangle(sb, e.CellBounds);

                }
                DrawCellBorder(e, Myg, IsShowTitleHBorder, IsShowTitleVBorder, TitleBorderColor, TitleBorderWidth);


            }

            //e.Handled = true;
            //e.PaintContent(e.CellBounds);

            if (e.ColumnIndex>-1&& e.RowIndex>-1)
            {

                if (IsUseAlternatingRowsColor)
                {

                    int i = e.RowIndex + 1;
                    if (i%2==0)
                    {
                        using (SolidBrush sb = new SolidBrush(AlternatingRowsColor))
                        {

                            Myg.FillRectangle(sb, e.CellBounds);
                        }
                    }
                    else
                    {
                        using (SolidBrush sb = new SolidBrush(MyCellBackColor))
                         {

                        Myg.FillRectangle(sb, e.CellBounds);
                        }
                    }


                }
                else
                {
                    using (SolidBrush sb = new SolidBrush(MyCellBackColor))
                    {

                        Myg.FillRectangle(sb, e.CellBounds);
                    }

                }
              



                if (Rows[e.RowIndex].Cells[e.ColumnIndex].Selected)
                {


                    using (SolidBrush sb = new SolidBrush(SelectedCellColor))
                    {



                        Myg.FillRectangle(sb, e.CellBounds);
                    }


                }

             
            DrawCellBorder(e, Myg ,IsShowCellHLine,IsShowCellVLine,MyCellBorderColor,MyCellBorderWidth);    

            }
 ////////////////////////////////////////////////////////

                
          e.Handled = true;
               e.PaintContent(e.CellBounds);



        }
      /// <summary>
      /// 画网格线
      /// </summary>
      /// <param name="e"></param>
      /// <param name="Myg"></param>
      /// <param name="ShowHline"></param>
      /// <param name="ShowVline"></param>
      /// <param name="cellBorderColor"></param>
      /// <param name="cellBorderWidth"></param>
        private void DrawCellBorder(DataGridViewCellPaintingEventArgs e, Graphics Myg,bool ShowHline, bool ShowVline
                                        ,Color cellBorderColor,float penWidth)
        {
            int pwidth = (int)penWidth / 2;
        

            if (ShowVline)
            {
                Point VPointStart1;
                 Point VPointEnd1;
                if (e.ColumnIndex==0)
                {
                    VPointStart1 = new Point(e.CellBounds.X +pwidth, e.CellBounds.Y);

                    VPointEnd1 = new Point(e.CellBounds.X +pwidth, e.CellBounds.Y + e.CellBounds.Height );

                }
                else
                {
                VPointStart1 = new Point(e.CellBounds.X- pwidth, e.CellBounds.Y ); 

                 VPointEnd1 = new Point(e.CellBounds.X - pwidth, e.CellBounds.Y + e.CellBounds.Height) ;
                }

           

                Point VPointStart2 = new Point(e.CellBounds.X + e.CellBounds.Width - pwidth-1, e.CellBounds.Y);
                Point VPointEnd2 = new Point(e.CellBounds.X + e.CellBounds.Width - pwidth-1, e.CellBounds.Y + e.CellBounds.Height + pwidth);


                using (Pen cellborderPen = new Pen(cellBorderColor, penWidth))
                {
                    Myg.DrawLine(cellborderPen, VPointStart1, VPointEnd1);
                    Myg.DrawLine(cellborderPen, VPointStart2, VPointEnd2);

                }
            }



            if (ShowHline)
            {
                Point HPointStart1 = new Point(e.CellBounds.X , e.CellBounds.Y);

                Point HPointEnd1 = new Point((int)(e.CellBounds.X + e.CellBounds.Width + (int)penWidth), e.CellBounds.Y);

                Point HPointStart2 = new Point(e.CellBounds.X , e.CellBounds.Y + e.CellBounds.Height);
                Point HPointEnd2 = new Point((int)(e.CellBounds.X + e.CellBounds.Width ), e.CellBounds.Y + e.CellBounds.Height);


                using (Pen cellborderPen = new Pen(cellBorderColor, penWidth))
                {
                    Myg.DrawLine(cellborderPen, HPointStart1, HPointEnd1);
                    Myg.DrawLine(cellborderPen, HPointStart2, HPointEnd2);

                }
            }


        }


        //******************************************************
        [Browsable(false)]
        public int SelectedIndex
        {
            get
            {
                return CurrentRow != null ? CurrentRow.Index : -1;
            }
            set
            {
                //BindingContext[DataSource].Position = value;
                if (Rows.Count == 0)
                {
                    return;
                }

                if (value >= 0 && value < Rows.Count)
                {
                    foreach (DataGridViewRow row in SelectedRows)
                    {
                        row.Selected = false;
                    }

                    Rows[value].Selected = true;
                    FirstDisplayedScrollingRowIndex = value;

                    if (selectedIndex >= 0 && selectedIndex <= Rows.Count)
                        jumpIndex = selectedIndex;

                    selectedIndex = value;
                    SelectIndexChange?.Invoke(this, value);
                }
            }
        }

        private int jumpIndex = -1;



        public delegate void OnSelectIndexChange(object sender, int index);

        public event OnSelectIndexChange SelectIndexChange;

       /// <summary>
       /// 回车跳转下一行
       /// </summary>
       /// <param name="e"></param>
        protected override void OnRowEnter(DataGridViewCellEventArgs e)
        {
            base.OnRowEnter(e);

            if (e.RowIndex == jumpIndex)
            {
                jumpIndex = -1;
                return;
            }

            if (selectedIndex != e.RowIndex)
            {
                selectedIndex = e.RowIndex;
                SelectIndexChange?.Invoke(this, e.RowIndex);
            }
        }

        private int selectedIndex = -1;

        public DataGridViewColumn AddColumn(string columnName, string dataPropertyName, int fillWeight = 100, DataGridViewContentAlignment alignment = DataGridViewContentAlignment.MiddleCenter, bool readOnly = true)
        {
            DataGridViewColumn column = new DataGridViewTextBoxColumn();
            column.HeaderText = columnName;
            column.DataPropertyName = dataPropertyName;
            column.Name = columnName;
            column.ReadOnly = readOnly;
            column.FillWeight = fillWeight;
            column.SortMode = DataGridViewColumnSortMode.NotSortable;
            column.DefaultCellStyle.Alignment = alignment;
            Columns.Add(column);
            return column;
        }

        public DataGridViewColumn AddCheckBoxColumn(string columnName, string dataPropertyName, int fillWeight = 100, bool readOnly = true)
        {
            DataGridViewColumn column = new DataGridViewCheckBoxColumn();
            column.HeaderText = columnName;
            column.DataPropertyName = dataPropertyName;
            column.Name = columnName;
            column.ReadOnly = readOnly;
            column.FillWeight = fillWeight;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            Columns.Add(column);
            return column;
        }

        public DataGridViewColumn AddButtonColumn(string columnName, string dataPropertyName, int fillWeight = 100, bool readOnly = true)
        {
            DataGridViewColumn column = new DataGridViewButtonColumn();
            column.HeaderText = columnName;
            column.DataPropertyName = dataPropertyName;
            column.Name = columnName;
            column.ReadOnly = readOnly;
            column.FillWeight = fillWeight;
            column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            Columns.Add(column);
            return column;
        }

        public virtual void ClearRows()
        {
            if (DataSource != null)
            {
                DataSource = null;
            }

            Rows.Clear();
        }

        public virtual void ClearColumns()
        {
            Columns.Clear();
        }

        public virtual void ClearAll()
        {
            ClearRows();
            ClearColumns();
        }

        public int AddRow(params object[] values)
        {
            return Rows.Add(values);
        }




    }
}
